﻿using DongFangGuoKai.WCSPlatform.WebApi.Extensions;
using DongFangGuoKai.WCSPlatform.WebApi.Utils;
using DongFangGuoKai.WMSPlatform.Commn.ExtendModule;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.FileSystemGlobbing.Internal;
using S7.Net;
using System.IO.Compression;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;

namespace DongFangGuoKai.WCSPlatform.WebApi.Controllers
{
    /// <summary>
    /// 初始化api
    /// </summary>
    [Route("api/[controller]/[action]"), ApiController, ApiExplorerSettings(GroupName = nameof(WCSApiVersions.V2))]
    public class InitPlcController : ControllerBase
    {
        private readonly Plc plc;
        private readonly PlcHeartbeatTool heartbeatTool;
        private readonly PlcDBAddress plcDBAddress;
        private readonly IWebHostEnvironment webHostEnvironment;
        private readonly PlcTaskManager plcTaskManager;
        private readonly ILogger<InitPlcController> logger;
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="plc"></param>
        /// <param name="heartbeatTool"></param>
        /// <param name="logger"></param>
        /// <param name="webHostEnvironment">下载日志</param>
        /// <param name="plcDBAddress">plc地址</param>
        public InitPlcController
        (
            Plc plc,
            PlcHeartbeatTool heartbeatTool,
            PlcDBAddress plcDBAddress,
            IWebHostEnvironment webHostEnvironment,
            PlcTaskManager plcTaskManager,
            ILogger<InitPlcController> logger
        )
        {
            this.plc = plc;
            this.heartbeatTool = heartbeatTool;
            this.plcDBAddress = plcDBAddress;
            this.webHostEnvironment = webHostEnvironment;
            this.plcTaskManager = plcTaskManager;
            this.logger = logger;
            //if (!plc.IsConnected) plc.Open();
        }
        /// <summary>
        /// 测试连接
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public ActionResult<WCSApiResponse> PlcConnected()
        {
            if (plc.IsConnected)
            {
                return this.Fail("连接已打开");
            }
            plc.Open();
            if (plc.IsConnected) return this.Success("连接成功");
            return this.Fail("连接失败");
        }

        /// <summary>
        /// 连接plc wcs开机
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public ActionResult<WCSApiResponse> PlcOpen()
        {
            try
            {
                if (plc.IsConnected)
                {
                    logger.LogError("连接以打开请勿重复点击");
                    return this.Fail("连接以打开请勿重复点击");
                }
                plc.Open();
                if (plc.IsConnected)
                {
                    heartbeatTool.StartHeartbeat(); // 在新线程中启动心跳定时器
                    //plcTaskManager.CheckTask();//开机前检查有没有未结束的任务
                    logger.LogInformation("wcs系统启动");
                    return this.Success("wcs系统启动");
                }
                else
                {
                    logger.LogError("wcs系统启动失败");
                    return this.Fail("wcs系统启动失败");
                }
            }
            catch (Exception ex)
            {
                logger.LogError("WCS程序启动失败:"+ex.Message);
                return this.Fail("WCS程序启动失败:" + ex.Message);
            }
        }
        /// <summary>
        /// 关闭plc wcs关机
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<ActionResult<WCSApiResponse>> PlcClose()
        {
            try
            {
                if (!plc.IsConnected)
                {
                    logger.LogError("关机失败:还未打开连接");
                    return await this.SuccessAsync("还未打开连接");
                }

               
                plc.Close();
                if (!plc.IsConnected)
                {
                    await heartbeatTool.StopHeartbeatAsync();//停止向plc发送心跳
                    logger.LogInformation("wcs系统退出");
                    return await this.FailAsync("wcs系统退出");
                }
                else return await this.FailAsync("关闭连接失败");
            }
            catch (Exception ex)
            {
                await heartbeatTool.StopHeartbeatAsync();//停止向plc发送心跳
                logger.LogError($"关机失败:{ex.Message}");
                return await this.FailAsync("关闭连接失败");
            }

        }

        /// <summary>
        /// 下载日志
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult DownloadWCSLogs()
        {
            string folderPath = Path.Combine(webHostEnvironment.ContentRootPath, "Logs");

            if (Directory.Exists(folderPath))
            {
                using (MemoryStream memoryStream = new MemoryStream())
                {
                    using (ZipArchive archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
                    {
                        DirectoryInfo directory = new DirectoryInfo(folderPath);

                        foreach (FileInfo file in directory.GetFiles())
                        {
                            using (FileStream fileStream = new FileStream(file.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                            {
                                ZipArchiveEntry entry = archive.CreateEntry(file.Name);

                                using (Stream entryStream = entry.Open())
                                {
                                    fileStream.CopyTo(entryStream);
                                }
                            }
                        }

                    }

                    memoryStream.Seek(0, SeekOrigin.Begin);
                    byte[] bytes = memoryStream.ToArray();
                    return File(bytes, "application/zip", "Logs.zip");
                }
            }
            else
            {
                return NotFound();
            }
        }

        
    }
}
//数据块地址构成例：DB1.DBW2 ~ [DB1]代表数据块  [W]代表数据类型  [2]代表偏移量

//Bool ：X或B

//Byte ：B

//Word/Int ：W

//Real/Dint/DWord ：D
